package com.atwisdom.star.common.util;

import io.jsonwebtoken.*;
import jodd.util.Base64;

import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.util.Date;

/**
 * @Desc：JWT工具类,处理加密、解密
 * @Author: joinly
 * @Date: 2018/8/23
 */
public class JwtUtils {

    /**
     *  生成jwt token
     * @param userId
     * @param jwtIss
     * @param ttlMillis
     * @param jwtSecret
     * @return
     */
    public static String createJWT(String userId, String jwtIss, long ttlMillis, String jwtSecret) {
        //签名算法
        SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;
        long nowMillis = System.currentTimeMillis();
        Date now = new Date(nowMillis);

        //密钥
        SecretKey secretKey = getSecretKey(jwtSecret);
        JwtBuilder builder = Jwts.builder().claim("userId", userId)
                //JWT的签发者
                .setIssuer(jwtIss)
                //签发时间
                .setIssuedAt(now)
                // 主题内容
                //.setSubject("{id:12, name: sb}")
                //签名算法以及密匙
                .signWith(signatureAlgorithm, secretKey);
        if (ttlMillis >= 0) {
            long expMillis = nowMillis + ttlMillis;
            Date expDate = new Date(expMillis);
            // 过期时间
            builder.setExpiration(expDate);
        }
        return builder.compact();
    }

    public static String createTenantJWT(String tenantId,  String userId, String jwtIss, long ttlMillis, String jwtSecret) {
        //签名算法
        SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;
        long nowMillis = System.currentTimeMillis();
        Date now = new Date(nowMillis);

        //密钥
        SecretKey secretKey = getSecretKey(jwtSecret);
        JwtBuilder builder = Jwts.builder().claim("userId", userId)
                .claim("Tenant_id", tenantId)
                //JWT的签发者
                .setIssuer(jwtIss)
                //签发时间
                .setIssuedAt(now)
                // 主题内容
                //.setSubject("{id:12, name: sb}")
                //签名算法以及密匙
                .signWith(signatureAlgorithm, secretKey);
        if (ttlMillis >= 0) {
            long expMillis = nowMillis + ttlMillis;
            Date expDate = new Date(expMillis);
            // 过期时间
            builder.setExpiration(expDate);
        }
        return builder.compact();
    }


    public static SecretKey getSecretKey(String jwtSecret) {
        byte[] encodedKey = Base64.decode(jwtSecret);
        SecretKey key = new SecretKeySpec(encodedKey, 0, encodedKey.length, "AES");
        return key;
    }

    /**
     * 解析JWT字符串
     * @param jwt
     * @param jwtSecret
     * @return
     * @throws Exception
     */
    public static Claims parseJWT(String jwt, String jwtSecret) throws Exception {
        SecretKey secretKey = getSecretKey(jwtSecret);
        return Jwts.parser().setSigningKey(secretKey).parseClaimsJws(jwt).getBody();
    }

    /**
     * 验证JWT
     * @param jwtStr
     * @param jwtSecret
     * @return
     */
    public static int validateJWT(String jwtStr, String jwtSecret) {
        try {
            Claims claims = parseJWT(jwtStr, jwtSecret);
            System.out.println("正确=====" + claims.toString());
            return SystemConstant.JWT_ERRCODE_OK;
        } catch (ExpiredJwtException e) {
            return SystemConstant.JWT_ERRCODE_EXPIRE;
        } catch (SignatureException e) {
            return SystemConstant.JWT_ERRCODE_FAIL;
        } catch (Exception e) {
            return SystemConstant.JWT_ERRCODE_FAIL;
        }
    }
}
